/**
 * 对于图节点的定义
 * 节点包含了所有以该节点起始的连边信息
 */
export class GraphNode<T, E> {
    value: T = null!
    edges: any[] = []
    constructor(edges: GraphEdge<E>[], value: T) {
        this.value = value
        this.edges = edges
    }
}

/**
 * 对于图连边的定义
 * 存储在graphnode中
 */
export class GraphEdge<E> {
    value: E = null!
    target: number
    constructor(target: number, value: E) {
        this.target = target
        this.value = value
    }
}

/**
 * 对于图的定义
 * 是GraphNode的数组，附加特殊方法 
 * node的索引是通过数组下标索引，不是map主键索引
 */
export class Graph<T, E> {
    nodes: GraphNode<T, E>[] = []
    constructor(nodes: GraphNode<T, E>[]) {
        this.nodes = nodes
    }


    /**
     * 将图转化为echarts图的形式，然后显示
     * @returns 
     */
    toEchartsGraph() {
        const categoryMap: string[] = []
        let nodes = this.nodes.map((node, i) => {
            let value = node.value as any
            let o: any = {
                name: i,
            }
            if (value !== null) {
                let c = categoryMap.indexOf(value.toString())
                if (c !== -1) {
                    o.category = c+1
                } else {
                    o.category = categoryMap.length+1
                    categoryMap.push(value.toString())
                }
            }
            if (node.value !== null) {
                o.itemStyle = {
                    borderWidth: 3,
                    borderType: 'solid',
                    borderColor: '#000000bb'
                }
            }
            return o
        })
        let edges: any[] = []
        this.nodes.forEach((node, s) => {
            node.edges.forEach((edge, i) => {
                let value = edge.value.toString()
                let o: any = {
                    source: s,
                    target: edge.target,
                    label: {
                        show: true,
                        formatter: value
                    },
                }
                if (edge.target === s) {
                    o.lineStyle = {
                        curveness: -0.1
                    }
                }
                edges.push(o)
            })
        })
        return {
            title: {
                text: '词法分析 DFA',
                top: 'bottom',
                left: 'right'
            },
            tooltip: {},
            legend: {
                data: ['', 'IDF', 'NUM', 'CEQ', 'LEQ', 'LES', 'NEQ', 'GEQ', 'GTR']
            },
            animationDurationUpdate: 1500,
            animationEasingUpdate: 'quinticInOut',
            series: [
                {
                    type: 'graph',
                    layout: 'circular',
                    categories: [{
                        name: "",
                    }, {
                        name: "IDF"
                    }, {
                        name: "NUM"
                    }, {
                        name: "CEQ"
                    }, {
                        name: "LEQ"
                    }, {
                        name: "LES"
                    }, {
                        name: "NEQ"
                    }, {
                        name: "GEQ"
                    }, {
                        name: "GTR"
                    }],
                    symbolSize: 50,
                    roam: true,
                    label: {
                        show: true
                    },
                    edgeSymbol: ['circle', 'arrow'],
                    edgeSymbolSize: [4, 10],
                    data: nodes,
                    // links: [],
                    links: edges,
                    lineStyle: {
                        opacity: 0.9,
                        width: 2,
                        curveness: 0.1
                    }
                }
            ],

        }
    }
}